const Service = require("egg").Service;
const { Builder, By, Key, until, error } = require("selenium-webdriver");
const axios = require("axios");
const chrome = require("selenium-webdriver/chrome");
const CDP = require("chrome-remote-interface");
const CryptoJS = require("crypto-js");
//salt
const salt = "37Z7PYH0SZWZDQOY";
function encryptNew(text) {
  let keyHex = CryptoJS.enc.Utf8.parse(salt); //
  let ivHex = CryptoJS.enc.Utf8.parse("y1pwrxe9vx8b0dio");
  let messageHex = CryptoJS.enc.Utf8.parse(text);
  let encrypted = CryptoJS.AES.encrypt(messageHex, keyHex, {
    iv: ivHex,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  return encrypted.toString();
}

// 使用axios转换图片URL为base64
async function imageUrlToBase64(url) {
  try {
    // 发送GET请求获取图片，设置响应类型为arraybuffer
    const response = await axios.get(url, {
      responseType: "arraybuffer",
      maxRedirects: 5, // 自动处理重定向
    });

    // 将二进制数据转换为base64
    const base64 = Buffer.from(response.data, "binary").toString("base64");
    // 构建完整的base64格式（包含MIME类型）
    return base64;
  } catch (error) {
    console.error("图片转换失败:", error.message);
    throw error;
  }
}

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

class HuNanTeleService extends Service {
  constructor(ctx) {
    super(ctx);
  }

  async sendTenRequests(mobile, num) {
    try {
      // for (let i = 0; i < num; i++) {
      //   let res = await axios.post(
      //     "https://hxv4.freelynet.com/tocinf/tc/submitOrder",
      //     {
      //       mebile: mobile,
      //       productCode: "20",
      //       channelCode: "FX-jinling",
      //       soldMobile: mobile,
      //       verifCode: "000000",
      //       orderNum: "",
      //       handlerUrl:
      //         "https://agentsys.freelynet.com/index/public_view_v4_new/?configui=3054&media=public&cu=FX-jinling&zxticketshu=&cSite=undefined#/",
      //       jyOldToken: "111",
      //     }
      //   );
      //   try {
      //     res = decodeURIComponent(res.data.data.redirectUrl);
      //     let data = res;
      //     const options = new chrome.Options();
      //     //链接cdp
      //     let cdpPort = 9222 + Math.floor(Math.random() * 100);
      //     options.addArguments(
      //       "--no-sandbox",
      //       "--disable-dev-shm-usage",
      //       "--window-size=430,1080",
      //       "--disable-blink-features=AutomationControlled",
      //       `--remote-debugging-port=${cdpPort}`, // 使用固定端口
      //       "--remote-debugging-address=0.0.0.0" // 允许所有地址连接
      //     );
      //     options.excludeSwitches("enable-automation");
      //     if (this.config.env === "prod") {
      //       options.addArguments("--headless=new");
      //     }
      //     const ua =
      //       "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
      //     options.addArguments(`user-agent=${ua}`);
      //     let service = new chrome.ServiceBuilder(this.config.chromeDriver);
      //     let driver = new Builder()
      //       .forBrowser("chrome")
      //       .setChromeService(service)
      //       .setChromeOptions(options)
      //       .build();
      //     await driver.executeScript(`window.open("${data}");`);
      //     await driver.sleep(1000);
      //     await driver.close();
      //     let allWindowHandles = await driver.getAllWindowHandles();
      //     await driver.switchTo().window(allWindowHandles[0]);
      //     let cdpClient;
      //     let targetUrl = "https://servicemp.114zhan.cn/OrderOnline/Log";
      //     try {
      //       // 使用正确的CDP连接方式
      //       cdpClient = await CDP({ port: cdpPort });
      //       await cdpClient.Runtime.enable();
      //       await cdpClient.Page.enable();
      //       await cdpClient.Network.enable();
      //       console.log(`CDP连接已建立，端口: ${cdpPort}`);
      //       // 用Promise封装请求监听，确保获取到CID后再继续
      //       const cidPromise = new Promise((resolve) => {
      //         cdpClient.Network.requestWillBeSent(async (params) => {
      //           const request = params.request;
      //           if (request.url.includes(targetUrl) && request.postData) {
      //             const cid = JSON.parse(request.postData).CID;
      //             // resolve({
      //             //   url: data,
      //             //   cid,
      //             // }); // 提取到CID后resolve
      //             if (cid === "d7333bd1dbe546939c4e1ba8076cafa9") {
      //               return data;
      //             }
      //           }
      //         });
      //       });
      //       await driver.sleep(2 * 1000);
      //       let hasCode = await driver.findElements(By.tagName("span"));
      //       await hasCode[10].click();
      //       cidResult = await Promise.race([
      //         cidPromise,
      //         new Promise((_, reject) =>
      //           setTimeout(
      //             () => reject(new Error("监听超时，未获取到目标请求")),
      //             10000
      //           )
      //         ),
      //       ]);
      //     } catch (error) {}
      //   } catch (error) {
      //     console.log(error);
      //     return {
      //       code: 500,
      //       msg: "该用户暂不支持办理（JL）",
      //     };
      //   }
      // }
      // 创建10个请求的Promise
      const requests = Array(num)
        .fill()
        .map(() => {
          // 假设使用fetch发送POST请求，根据实际需求可以修改请求方式和参数格式
          return axios
            .post("https://hxv4.freelynet.com/tocinf/tc/submitOrderVersion2", {
              mebile: encryptNew(mobile),
              productCode: "20",
              channelCode: "FX-jinling",
              soldMobile: encryptNew(mobile),
              verifCode: "000000",
              orderNum: "",
              handlerUrl:
                "https://agentsys.freelynet.com/index/public_view_v4_new/?configui=3054&media=public&cu=FX-jinling&zxticketshu=&cSite=undefined#/",
              jyOldToken: "111",
            })
            .then((zhRes) => {
              // console.log(zhRes);
              if (zhRes.data.code != 0 && zhRes.data.code != 200) {
                return zhRes.data.message;
              } else {
                return decodeURIComponent(zhRes.data.data.redirectUrl);
              }
            });
        });

      // 等待所有请求完成
      const results = await Promise.all(requests);

      // 返回所有请求的结果数组
      return results;
    } catch (error) {
      console.error("请求过程中发生错误:", error);
      throw error; // 重新抛出错误，让调用者可以处理
    }
  }

  /**
   * 获取页面的cid
   * @param {*} driver
   * @param {*} url
   */
  async getCid(driver, cdpPort, url) {
    let cdpClient;
    let targetUrl = "https://servicemp.114zhan.cn/OrderOnline/Log";
    await driver.manage().deleteAllCookies();
    await driver.executeScript(`window.open("${url}");`);
    await driver.sleep(1000);
    await driver.close();
    let allWindowHandles = await driver.getAllWindowHandles();
    await driver.switchTo().window(allWindowHandles[0]);
    let cidResult;
    try {
      // 使用正确的CDP连接方式
      cdpClient = await CDP({ port: cdpPort });
      await cdpClient.Runtime.enable();
      await cdpClient.Page.enable();
      await cdpClient.Network.enable();
      console.log(`CDP连接已建立，端口: ${cdpPort}`);
      // 用Promise封装请求监听，确保获取到CID后再继续
      const cidPromise = new Promise((resolve) => {
        cdpClient.Network.requestWillBeSent(async (params) => {
          const request = params.request;
          if (request.url.includes(targetUrl) && request.postData) {
            const cid = JSON.parse(request.postData).CID;
            resolve({
              url,
              cid,
            });
          }
        });
      });
      // let hasCode = await driver.findElements(By.tagName("span"));
      // await hasCode[10].click();
      await driver.executeScript(`
        let  hasCode = document.getElementsByTagName("span");
        hasCode[10].click(); 
      `);
      cidResult = await Promise.race([
        cidPromise,
        new Promise((_, reject) =>
          setTimeout(
            () => reject(new Error("监听超时，未获取到目标请求")),
            10000
          )
        ),
      ]);
      return cidResult;
    } catch (error) {
      console.log(error);
    }
  }

  async getCode(body) {
    let allStartTime = new Date().valueOf();
    let { mobile, ua, productCode } = body;
    let url = "";
    if (!mobile || !ua || !productCode) {
      // 可以自定义状态码
      this.ctx.status = 500;
      this.ctx.msg = "缺少必要参数";
      return;
    }

    if (!/^1[3456789]\d{9}$/.test(mobile)) {
      this.ctx.status = 500;
      this.ctx.msg = "请填写正确手机号";
      return;
    }

    // 设置最大重试次数
    const MAX_RETRIES = 10;
    let currentRetry = 0;
    let type = "";
    let urlRes;
    try {
      // const requests = Array(MAX_RETRIES)
      //   .fill()
      //   .map((item, index) => {
      //     // 假设使用fetch发送POST请求，根据实际需求可以修改请求方式和参数格式
      //     return axios.post(
      //       "http://192.168.1.20:9701/api/v1/HuNanTele/getCID",
      //       {
      //         mobile,
      //       }
      //     );
      //   });

      // 等待所有请求完成
      // let results = await Promise.all(requests);
      // for (let i = 0; i < MAX_RETRIES; i++) {
      //   try {
      //     let request = await axios.post(
      //       "http://192.168.1.20:9701/api/v1/HuNanTele/getCID",
      //       {
      //         mobile,
      //       }
      //     );

      //     if (request.data.data.cid == "d7333bd1dbe546939c4e1ba8076cafa9") {
      //       url = request.data.data.url;
      //       break;
      //     }
      //   } catch (error) {}
      // }
      // results = results.map((item) => {
      //   return item.data.data;
      // });
      // results = results.filter(
      //   (item) => item.cid == "d7333bd1dbe546939c4e1ba8076cafa9"
      // );
      // if (results.length > 0) {
      //   url = results[0].url;
      // } else {
      urlRes = await this.sendTenRequests(mobile, MAX_RETRIES);
      if (urlRes[0].indexOf("https") == -1) {
        this.ctx.status = 500;
        this.ctx.msg = `发送验证码失败，(该用户不符合办理资格)`;
        return;
      }

      // if (!res) {
      //   this.ctx.status = 500;
      //   this.ctx.msg = `发送验证码失败，请重试（JL_未找到订单）`;
      //   this.ctx.body = {
      //     error: "未找到订单(JL)",
      //   };
      //   return;
      // }
      this.app.logger.info(
        `[纵横请求时长]:`,
        `${new Date().valueOf() - allStartTime}ms\n`
      );
    } catch (error) {
      this.ctx.status = 500;
      this.ctx.msg = `发送验证码失败，请稍后重试(${error.message})`;
      this.ctx.body = {
        error: error.message || "请求处理异常",
      };
      return;
    }

    let userId = mobile + "_" + productCode;
    // 为用户获取窗口
    let driver = await this.service.seleniumPool.getUserWindow(userId);
    if (!driver) {
      let window = await this.service.seleniumPool.acquire(userId);

      if (!window) {
        this.ctx.status = 500;
        this.ctx.msg = "活动太火爆了，请稍后再试(jl)";
        return;
      }
    }
    driver = await this.service.seleniumPool.getUserWindow(userId);
    let cdpPort = driver.cdpPort;
    driver = driver.driver;
    try {
      let check = false;
      for (let i = 0; i < MAX_RETRIES; i++) {
        let cidRes = await this.getCid(driver, cdpPort, urlRes[i]);
        console.log(cidRes);
        try {
          if (cidRes.cid == "d7333bd1dbe546939c4e1ba8076cafa9") {
            check = true;
            url = cidRes.url;
            break;
          }
        } catch (error) {}
      }
      if (!check) {
        this.ctx.status = 500;
        this.ctx.msg = "服务机查找失败，请稍后再试(jl)";
        return;
      }
      // let getWindowTime = new Date().valueOf();
      // await driver.executeScript(`window.open("${url}");`);
      // await driver.sleep(1000);
      // await driver.close();
      // let allWindowHandles = await driver.getAllWindowHandles();
      // await driver.switchTo().window(allWindowHandles[0]);
      // let hasCode = await driver.findElements(By.tagName("span"));
      // await hasCode[10].click();

      //   let timeCount = 10 * 1000;
      //   let startTime = new Date().valueOf();
      //   let imageSrc = "";
      //   while (!imageSrc && new Date().valueOf() - startTime < timeCount) {
      //     try {
      //       imageSrc = await driver.executeScript(`
      //   const elements = document.getElementsByClassName('yidun_bg-img');
      //   return elements.length > 0 ? elements[0].src : null;
      // `);
      //     } catch (error) {}
      //   }
      //   if (new Date().valueOf() - startTime >= timeCount) {
      //     this.ctx.status = 500;
      //     this.ctx.msg = "发送验证码失败，请求超时(jl)";
      //     //this.ctx.service.seleniumPool.releaseByUser(userId);
      //     return;
      //   }
      //   let imageTime = new Date().valueOf();
      //   // console.log("展示图片耗时:", imageTime - startTime);
      //   // console.log("总耗时[0]：", new Date().valueOf() - allStartTime);
      //   const base64Image = await imageUrlToBase64(imageSrc);
      //   let baseTime = new Date().valueOf();
      //   // console.log("转化base64耗时:", baseTime - imageTime);
      //   // console.log("总耗时[0]：", new Date().valueOf() - allStartTime);
      //   let res = await axios.post(
      //     "http://api.jfbym.com/api/YmServer/customApi",
      //     {
      //       image: base64Image,
      //       //   direction: "bottom",
      //       //   click_num: 3,
      //       token: "9Zr0B_5TxfcpX2Dg9Wo-viFURztGJJzT8El-ikhV0CQ",
      //       type: "30104",
      //       source_site: "https://necaptcha.nosdn.127.net",
      //     }
      //   );
      //   let imageReadTime = new Date().valueOf();
      //   // console.log("识别图片耗时：", imageReadTime - baseTime);
      //   // console.log("总耗时[0]：", new Date().valueOf() - allStartTime);
      //   this.app.logger.info(
      //     "[CODE_PAGE_REQUEST_LOG]",
      //     `识别参数图片链接:${imageSrc}\n返回参数:${JSON.stringify(
      //       res.data.data
      //     )}`
      //   );
      //   if (res.data.data.code === 0) {
      //     let position = res.data.data.data.split("|");
      //     position = position.map((item) => {
      //       let p = item.split(",");
      //       return {
      //         // x: Number(p[0]) + 80 + randomInt(10, 20),
      //         // y: Number(p[1]) + randomInt(5, 10),
      //         x: parseInt((Number(p[0]) + 27) * 0.7),
      //         y: parseInt((Number(p[1]) + 470) * 0.7),
      //       };
      //     });
      //     // console.log("处理点击耗时：", new Date().valueOf() - imageReadTime);
      //     const actions = driver.actions({ async: true });
      //     await actions
      //       .move({
      //         x: position[0].x,
      //         y: position[0].y,
      //         duration: randomInt(0, 10),
      //       })
      //       .click()
      //       .move({
      //         x: position[1].x,
      //         y: position[1].y,
      //         duration: randomInt(0, 10),
      //       })
      //       .click()
      //       .move({
      //         x: position[2].x,
      //         y: position[2].y,
      //       })
      //       .click()
      //       .perform();
      //     // let clickTime = new Date().valueOf();
      //     // console.log("点击耗时:", clickTime - imageReadTime);
      //     // console.log("总耗时[0]：", new Date().valueOf() - allStartTime);
      //     await driver.sleep(3000);
      //     try {
      //       // let alert = await driver.wait(until.alertIsPresent(), 5000);
      //       // let alertText = await alert.getText();
      //       // await alert.accept();
      //       // console.log("弹窗耗时:", new Date().valueOf() - clickTime);
      //       // console.log("总耗时：", new Date().valueOf() - allStartTime);
      //       // let hasCode = await driver.findElements(By.tagName("span"));
      //       // let alertText = await hasCode[10].getText();
      //       // if (alertText.indexOf("获取") == -1) {
      //       //   alertText = "发送成功！";
      //       // } else {
      //       //   throw "发送失败！";
      //       // }
      //       let alertText = "发送成功";
      //       this.ctx.status = 200;
      //       this.ctx.msg = alertText;
      //       this.ctx.body = {
      //         orderNumber: url.split("=")[1],
      //         url,
      //       };
      //     } catch (err) {
      //       this.ctx.status = 500;
      //       this.ctx.msg = "发送失败！再试一次吧";
      //       this.ctx.body = {
      //         orderNumber: url.split("=")[1],
      //         url,
      //         err,
      //       };
      //       //this.ctx.service.seleniumPool.releaseByUser(userId);
      //     }
      //   }
    } catch (error) {
      console.log(error);
      this.ctx.status = 500;
      this.ctx.msg = "发送验证码失败，请稍后再试一次吧";
      this.ctx.body = {
        error: error.message,
      };
      //this.ctx.service.seleniumPool.releaseByUser(userId);
    }
  }

  async submit(body) {
    let { mobile, ua, productCode, vCode } = body;

    if (!mobile || !ua || !productCode || !vCode) {
      // 可以自定义状态码
      this.ctx.status = 500;
      this.ctx.body = {
        message: "缺少必要参数",
      };
      return;
    }

    if (vCode.length != 4) {
      // 可以自定义状态码
      this.ctx.status = 500;
      this.ctx.body = {
        message: "请输入四位验证码",
      };
      return;
    }

    if (!/^1[3456789]\d{9}$/.test(mobile)) {
      this.ctx.status = 500;
      this.ctx.msg = "请填写正确手机号";
      return;
    }

    let userId = mobile + "_" + productCode;
    // 为用户获取窗口
    let driver = await this.service.seleniumPool.getUserWindow(userId);
    if (!driver) {
      this.ctx.status = 500;
      this.ctx.msg = "验证码超时,请获取验证码";
      return;
    }
    driver = driver.driver;
    try {
      let alert = await driver.wait(until.alertIsPresent(), 300);
      if (alert) {
        await alert.accept();
      }
    } catch (error) {}
    try {
      //填写验证码
      let verifCodeList = await driver.findElements(By.id("code_qd"));
      await verifCodeList[0].sendKeys(vCode);
      await driver.sleep(1000);

      //提交
      let sureDom = await driver.findElements(By.className("btnstyle"));
      await sureDom[0].click();
      await driver.sleep(1000);
      try {
        let alert = await driver.wait(until.alertIsPresent(), 2000);
        let alertText = await alert.getText();
        try {
          let image = await driver.takeScreenshot();
          this.app.logger.info(
            `[${productCode}_${mobile}_${vCode}]`,
            `页面:${image}\n`
          );
        } catch (error) {}

        if (
          alertText.indexOf("验证码") > -1 ||
          alertText.indexOf("失败") > -1
        ) {
          this.ctx.status = 500;
          this.ctx.body = {
            code: 500,
            message: alertText,
          };
          return;
        }
        this.ctx.status = 200;
        this.ctx.body = {
          code: alertText.indexOf("成功") > -1 ? 0 : 500,
          message: alertText || "提交成功！",
        };
      } catch (error) {
        let currentUrl = "";
        try {
          currentUrl = await driver.getCurrentUrl();
        } catch (error) {}
        this.ctx.status = 200;
        this.ctx.body = {
          code: 0,
          message: "提交成功！",
          err: error,
          page: currentUrl,
        };
      }
    } catch (error) {
      console.log(error);
      this.ctx.status = 500;
      this.ctx.msg = "办理失败";
      this.ctx.body = {
        error: error,
      };
    }
  }
}

module.exports = HuNanTeleService;
